package sma.iss.remote;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Collection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import sma.interf.BindUtil;
import sma.interf.ICalculateIss;
import sma.interf.SyncCalculateImpl;

public class ParallelMgr {
	/** Logger for this class. */
	private final static Logger LOGGER = LoggerFactory.getLogger(ParallelMgr.class);

	private final static String[] REMOTE_HOSTS = new String[] { "marsolle-2", "localhost" };
	// private final static String[] REMOTE_HOSTS = new String[] { "vc2176-vmcmh7.corp.capgemini.com", "localhost" };
	// private final static String[] REMOTE_HOSTS = new String[] { "pc-de-christine", "localhost" };

	private Collection<ICalculateIss> allRemoteCalc = null;

	/**
	 * One monothread calculator
	 * 
	 * @return
	 */
	public Collection<ICalculateIss> getAllAvailableCalculatorsO() {
		if (allRemoteCalc != null) {
			return allRemoteCalc;
		}
		Collection<ICalculateIss> result = new ArrayList<ICalculateIss>();
		try {
			result.add(new SyncCalculateImpl());
		} catch (RemoteException e) {
			LOGGER.error("", e);
		}
		allRemoteCalc = result;
		return result;
	}

	/**
	 * Several rmote calculators + one internal
	 * 
	 * @return
	 */
	public Collection<ICalculateIss> getAllAvailableCalculators() {
		if (allRemoteCalc != null) {
			return allRemoteCalc;
		}
		LOGGER.info("start exploration for calculators...");
		Collection<ICalculateIss> result = new ArrayList<ICalculateIss>();
		try {
			result.add(new SyncCalculateImpl());
		} catch (RemoteException e) {
			LOGGER.error("", e);
		}
		for (int i = 0; i < REMOTE_HOSTS.length; i++) {
			String remoteHost = REMOTE_HOSTS[i];
			result.addAll(this.getAvailableCalculators(remoteHost));
		}
		allRemoteCalc = result;
		LOGGER.info("nb calculators found {}", result.size());
		return result;
	}

	public Collection<ICalculateIss> getAvailableCalculators(String remoteHost) {
		Collection<ICalculateIss> result = new ArrayList<ICalculateIss>();
		Registry registry;
		try {
			registry = LocateRegistry.getRegistry(remoteHost);
			String[] lstNames = registry.list();
			LOGGER.info("From Registry, lstNames.length={}", lstNames.length);
			for (int i = 0; i < lstNames.length; i++) {
				String name = lstNames[i];
				if (name.startsWith(BindUtil.BASE_NAME)) {
					LOGGER.info("trying {}", name);
					ICalculateIss stub = (ICalculateIss) registry.lookup(name);
					try {
						String hostName = stub.getHostName();
						LOGGER.info("remote calculator {} is on stub.getHostName()={}", name, hostName);
						result.add(stub);
					} catch (RemoteException e) {
						LOGGER.warn("Problem with {}", name);
					}
				}

			}

		} catch (Exception e) {
			LOGGER.error("", e);
		}
		return result;
	}
}
